//This is the StatsLogon GUI object that represents a viewable panel representing logon controls

//import only what we need to speed things up
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.DefaultListModel;
import javax.swing.ListModel;
import javax.swing.AbstractListModel;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JScrollPane;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.BorderLayout;
import java.awt.Insets;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Font;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.Image;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;

public class GameLoad extends JPanel implements ActionListener {
	
	//declare class instance vars
	private Image background;
	private Image scaledbg;
	private Dimension prevsize;
	private JLabel vstxt_lbl;
	private JList games_lst;
	private JButton loadgame_btn;
	private JButton newgame_btn;
	private JButton goback_btn;
	private String player1;
	private String player2;
	//common colors
	public static Color bgnorm = new Color(188, 143, 70);
	public static Color fgnorm = new Color(56, 5, 3);
	public static Color bgalt1 = new Color(221, 173, 98);
	public static Color fgalt1 = new Color(93, 15, 2);
	public static Color fgalt2 = new Color(242, 79, 1);
	
	//our constructor
	public GameLoad() {
		
		//call our ancestor
		super();
		
		//build our layout with GridBag
		//assuming an invisible grid of 14 x 10
		this.setLayout(new GridBagLayout());
		
		//add a filler panel to fill the entire first column (1st-10th row) (1st column)
		JPanel temppan1 = new JPanel();
		temppan1.setOpaque(false);
		temppan1.setVisible(true);
		this.add(temppan1, new GridBagConstraints( 0, 0, 1, 10, 0.1, 1.0, 
			GridBagConstraints.LINE_START, GridBagConstraints.VERTICAL, new Insets(0,0,0,0),
			0, 0));
		//add a filler panel to fill the entire first row, sorta (2nd-13th column) (1st row)
		JPanel temppan2 = new JPanel();
		temppan2.setOpaque(false);
		temppan2.setVisible(true);
		this.add(temppan2, new GridBagConstraints( 1, 0, 12, 1, 0.85, 0.05, 
			GridBagConstraints.PAGE_START, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),
			0, 0));
		//add a filler panel to fill the entire last column (1st-10th row) (14th column)
		JPanel temppan3 = new JPanel();
		temppan3.setOpaque(false);
		temppan3.setVisible(true);
		this.add(temppan3, new GridBagConstraints(13, 0, 1, 9, 0.1, 1.0, 
			GridBagConstraints.LINE_END, GridBagConstraints.VERTICAL, new Insets(0,0,0,0),
			0, 0));
		//add our main panel to fill up center (2nd-13th column) (2nd-9th row)
		JPanel mainpan = new JPanel();
			//setup another GridBag
			//assuming an invisible grid of 12 x 10
			mainpan.setLayout(new GridBagLayout());
			//add header label to all of the top 2 row (1st-12th column) (1st-2nd row)
			JLabel header1 = new JLabel();
			header1.setText("Load or Start a Game");
			header1.setFont(new Font("Franklin Gothic Heavy", Font.PLAIN, 24));
			header1.setForeground(GameLoad.fgnorm);
			mainpan.add(header1, new GridBagConstraints( 0, 0, 12, 2, 1.0, 0.5, 
				GridBagConstraints.PAGE_START, GridBagConstraints.BOTH, new Insets(10,10,0,10),
				0, 0));
			//add player vs player label for the 3rd row (1st-12th column) (3rd row)
			this.vstxt_lbl = new JLabel();
			this.vstxt_lbl.setText("Player vs Player");
			this.vstxt_lbl.setFont(new Font("Franklin Gothic Heavy", Font.PLAIN, 18));
			this.vstxt_lbl.setForeground(GameLoad.fgalt2);
			mainpan.add(this.vstxt_lbl, new GridBagConstraints( 0, 2, 12, 1, 1.0, 0.2, 
				GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,10,0,10),
				0, 0));
			//add secondary header label to the 4th row (1st-12th column) (4th row)
			JLabel header2 = new JLabel();
			header2.setText("Available Saved Games");
			header2.setFont(new Font("Franklin Gothic Heavy", Font.PLAIN, 20));
			header2.setForeground(GameLoad.fgalt2);
			mainpan.add(header2, new GridBagConstraints( 0, 3, 12, 1, 1.0, 0.3, 
				GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(0,10,0,10),
				0, 0));
			//add game list through center area (1st-12th column) (5th-8th row)
			//what a pain in the ass, JList does not implement scroll functionality
			// it must be nested inside something that does, like a JScrollPane
			this.games_lst = new JList();
			this.games_lst.setFont(new Font("Franklin Gothic Heavy", Font.PLAIN, 16));
			this.games_lst.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
			JScrollPane tmppanescroll = new JScrollPane();
			tmppanescroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
			tmppanescroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
			tmppanescroll.setViewportView(this.games_lst);
			mainpan.add(tmppanescroll, new GridBagConstraints( 0, 4, 12, 4, 1.0, 0.8, 
				GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,10,0,10),
				0, 0));
			//add load game button to 9th row (1st-12th column) (9th row)
			this.loadgame_btn = new JButton();
			this.loadgame_btn.addActionListener(this);
			this.loadgame_btn.setText("Load Game");
			this.loadgame_btn.setFont(new Font("Franklin Gothic Heavy", Font.PLAIN, 20));
			this.loadgame_btn.setForeground(GameLoad.fgalt1);
			this.loadgame_btn.setBackground(GameLoad.bgalt1);
			mainpan.add(this.loadgame_btn, new GridBagConstraints( 0, 8, 12, 1, 1.0, 0.2, 
				GridBagConstraints.CENTER, GridBagConstraints.VERTICAL, new Insets(0,0,0,0),
				0, 0));
			//add new game button to 9th row (1st-12th column) (9th row)
			this.newgame_btn = new JButton();
			this.newgame_btn.addActionListener(this);
			this.newgame_btn.setText("New Game");
			this.newgame_btn.setFont(new Font("Franklin Gothic Heavy", Font.PLAIN, 20));
			this.newgame_btn.setForeground(GameLoad.fgalt1);
			this.newgame_btn.setBackground(GameLoad.bgalt1);
			mainpan.add(this.newgame_btn, new GridBagConstraints( 0, 9, 12, 1, 1.0, 0.2, 
				GridBagConstraints.CENTER, GridBagConstraints.VERTICAL, new Insets(0,0,0,0),
				0, 0));
		mainpan.setBackground(GameLoad.bgalt1);
		mainpan.setOpaque(true);
		mainpan.setVisible(true);
		this.add(mainpan, new GridBagConstraints( 1, 1, 12, 8, 1.0, 0.8, 
			GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,0,0,0),
			0, 0));
		//add a filler panel to fill the entire last row, sorta (2nd-11th column) (10th row)
		JPanel temppan4 = new JPanel();
		temppan4.setOpaque(false);
		temppan4.setVisible(true);
		this.add(temppan4, new GridBagConstraints( 1, 9, 10, 1, 0.85, 0.05, 
			GridBagConstraints.PAGE_END, GridBagConstraints.HORIZONTAL, new Insets(0,0,0,0),
			0, 0));
		//add our go-back button
		//we want this to be at the bottom right corner cell (10th row) (12th-13th column)
		this.goback_btn = new JButton();
		this.goback_btn.setText("Go Back");
		this.goback_btn.setFont(new Font("Franklin Gothic Heavy", Font.PLAIN, 20));
		this.goback_btn.setBackground(GameLoad.bgnorm);
		this.goback_btn.setForeground(GameLoad.fgnorm);
		this.goback_btn.addActionListener(this);
		this.add(this.goback_btn, new GridBagConstraints(11, 9, 2, 1, 0.0, 0.0, 
			GridBagConstraints.LINE_START, GridBagConstraints.NONE, new Insets(0,0,0,0),
			0, 0));
			
		
		//set a reasonable size to match the ratio of our splash image
		this.setPreferredSize(new Dimension(500, 375));
		
		//try to get our splash image
		//if we cannot retrieve the image, it is somewhat serious
		//but I don't know what we could do from that point on :(
		try{
			background = ImageIO.read(new File("images\\SplashMedium.jpg"));
		}catch (IOException EXC){
			//this likely means there was some problem accessing the image file
		}catch (IllegalArgumentException EXC){
			//this likely means that for some reason we couldn't create the File object
		}
		
		//setup our text etc defaults
		//tbc
		ArrayList<Date> tmpdates = new ArrayList<Date>();
			tmpdates.add(new Date());
			this.setGames(tmpdates);
		
		//setup visibilities
		this.setVisible(true);
		this.setOpaque(true);
		
	}
	
	//override this so that we can customize drawing of the component
	//specifically so that we always have our pretty splash screen behind us :D
	public void paintComponent(Graphics g) {
		
		//call our ancestor
		super.paintComponent(g);
		
		System.out.println("$1GameLogon: painting...");
		
		//getSize is a retarded method, as such it requires
		//  we pass a Dimension object that it will use by referrence to store the size
		//the retarded part is that it also returns the same Dimension object
		//  go figure...
		Dimension panelsize = new Dimension(0,0);
		this.getSize(panelsize);
		
		//check if previous size has been declared yet
		if (this.prevsize == null){
			this.prevsize = new Dimension(panelsize);
		}
		
		//check if we need to rescale the image
		// this can occur if the component size changed
		// or it can occur if the image has not been scaled yet
		if (this.scaledbg == null || !panelsize.equals(this.prevsize)){
			this.scaledbg = background.getScaledInstance(panelsize.width,
			panelsize.height, Image.SCALE_SMOOTH);
		}
		g.drawImage(scaledbg, 0, 0, null);
		
		//reset the previous scale size
		this.prevsize = new Dimension(panelsize);
		
	}
	
	
	//hidden convenience method for adding the player names to the drop-down list
	private void setGames(ArrayList<Date> newgames) {
		
		//clear out the existing games
		//DefaultListModel tmpmod = (DefaultListModel)(AbstractListModel)(ListModel)(this.games_lst.getModel());
		//ListModel tmpmodshit = this.games_lst.getModel();
		DefaultListModel tmpmod = new DefaultListModel();
		tmpmod.removeAllElements();
		this.games_lst.setModel(tmpmod);
		//dont do anything if the list is empty
		if (newgames.isEmpty()){
			return;
		}
		//for user convenience, we should make sure the list is sorted
		//lets have fun and try the java default algorithm
		if (newgames.size() > 1){
			Collections.sort(newgames);
		}
		for (int i=0; i<newgames.size(); ++i){
			tmpmod.addElement(newgames.get(i));
		}
		this.games_lst.setModel(tmpmod);
		
	}
	//convenience method for retrieving player data from Storage
	public void getGames(String player1, String player2) {
		
		//also set the player vs player label text
		this.vstxt_lbl.setText(player1 + " vs " + player2);
		//grab games
		ArrayList<Date> tmpgames = UIController.getGames(player1, player2);
		this.player1 = player1;
		this.player2 = player2;
		//verify if there are any game to load
		if (!tmpgames.isEmpty()){
			System.out.println("GAMELOAD: saved games exist...");
			//there are games that can be loaded, we should continue and allow the user to decide
			this.setGames(tmpgames);
		}else{
			System.out.println("GAMELOAD: no saved games exist, skipping.");
			//there are no games to load, we should skip ahead and setup new game with logic
			ArrayList<String> tmplist = new ArrayList<String>();
			tmplist.add(this.player1);
			tmplist.add(this.player2);
			UIController.setGamePlayers(tmplist);
			//switch to game board normally so that it will jump into setup mode
			UIController.changeState("GameView");
		}
		
	}
	
	//hidden convenience method for attempting to load the selected game instance
	private void loadGame() {
		
		if (this.games_lst.getSelectedValue() != null){
			Date tmpdate = ((Date)(this.games_lst.getSelectedValue()));
			ArrayList<String> tmplist = new ArrayList<String>();
			tmplist.add(this.player1);
			tmplist.add(this.player2);
			boolean success = UIController.loadGame(tmpdate, tmplist);
			tmplist = UIController.getGamePlayers();
			if (success){
				//tell gameboard to prepare a loaded game and to skip setup procedures
				try{
					((GameView)UIController.grabState("GameView")).gameboard.prepareLoadGame(tmplist);
				}catch (NullPointerException EXC){
					System.out.println("game load failed to grab isntance of game view");
				}
				UIController.changeState("GameView");
			}else{
				System.out.println("failed to load game saved during " + tmpdate);
				this.showInfoNotice("Failed to load the game saved on " + tmpdate, "Unexpected Error");
			}
		}
		
	}
	
	//hidden convenience method for attempting to start a new game
	private void newGame() {
		
		//setup new game with logic
		ArrayList<String> tmplist = new ArrayList<String>();
		tmplist.add(this.player1);
		tmplist.add(this.player2);
		UIController.setGamePlayers(tmplist);
		//switch to game board normally so that it will jump into setup mode
		UIController.changeState("GameView");
		
	}
	
	//hidden convenience method for showing the user an information notice
	private void showInfoNotice(String info, String title) {
		
		this.repaint();
		JOptionPane.showMessageDialog(this, info, title, JOptionPane.INFORMATION_MESSAGE);
		
	}
	
	
	//implement ActionListener
	public void actionPerformed(ActionEvent EVE) {
		
		//determine the caller
		Object tmpobj = EVE.getSource();
		if (tmpobj.equals(this.goback_btn)){
			UIController.changeState("MainView");
		}else if (tmpobj.equals(this.loadgame_btn)){
			//attempt load
			this.loadGame();
		}else if (tmpobj.equals(this.newgame_btn)){
			//start new
			this.newGame();
		}
		
	}
	
}